package com.sy.simpleegg.util

import android.util.Log
import java.util.Locale

/**
 * Author by Winds on 2016/10/18.
 * Email heardown@163.com.
 */
object ByteUtil {

    //public static void main(String[] args) {
    //    byte[] bytes = {
    //        (byte) 0xab, 0x01, 0x11
    //    };
    //    String hexStr = bytes2HexStr(bytes);
    //    System.out.println(hexStr);
    //    System.out.println(hexStr2decimal(hexStr));
    //    System.out.println(decimal2fitHex(570));
    //    String adc = "abc";
    //    System.out.println(str2HexString(adc));
    //    System.out.println(bytes2HexStr(adc.getBytes()));
    //}
    fun int2HexStr(target: Int, len: Int, isLowFirst: Boolean): String? {
        var hexStr = Integer.toHexString(target)
        while (hexStr.length < len) {
            hexStr = "0$hexStr"
        }
        return if (len >= 4 && isLowFirst) {
            var temp = ""
            for (i in 0 until len / 2) {
                temp += hexStr.substring(hexStr.length - (i + 1) * 2, hexStr.length - i * 2)
            }
            temp.uppercase()
        } else {
            hexStr.uppercase()
        }
    }

    fun long2HexStr(target: Long, len: Int, isLowFirst: Boolean): String {
        var hexStr = target.toString(16)
        while (hexStr.length < len) {
            hexStr = "0$hexStr"
        }
        return if (len >= 4 && isLowFirst) {
            var temp = ""
            for (i in 0 until len / 2) {
                temp += hexStr.substring(hexStr.length - (i + 1) * 2, hexStr.length - i * 2)
            }
            temp.uppercase()
        } else {
            hexStr.uppercase()
        }
    }

    /**
     * 字节数组转换成对应的16进制表示的字符串
     *
     * @param src
     * @return
     */
    fun bytes2HexStr(src: ByteArray?): String {
        val builder = StringBuilder()
        if (src == null || src.size <= 0) {
            return ""
        }
        val buffer = CharArray(2)
        for (i in src.indices) {
            buffer[0] = Character.forDigit(src[i].toInt() ushr 4 and 0x0F, 16)
            buffer[1] = Character.forDigit(src[i].toInt() and 0x0F, 16)
            builder.append(buffer)
        }
        return builder.toString().uppercase(Locale.getDefault())
    }

    /**
     * 十六进制字节数组转字符串
     *
     * @param src 目标数组
     * @param dec 起始位置
     * @param length 长度
     * @return
     */
    fun bytes2HexStr(src: ByteArray?, dec: Int, length: Int): String {
        val temp = ByteArray(length)
        System.arraycopy(src, dec, temp, 0, length)
        return bytes2HexStr(temp)
    }

    /**
     * 16进制字符串转10进制数字
     *
     * @param hex
     * @return
     */
    fun hexStr2decimal(hex: String): Long {
        return hex.toLong(16)
    }

    /**
     * 把十进制数字转换成足位的十六进制字符串,并补全空位
     *
     * @param num
     * @return
     */
    fun decimal2fitHex(num: Long): String {
        val hex = java.lang.Long.toHexString(num).uppercase(Locale.getDefault())
        return if (hex.length % 2 != 0) {
            "0$hex"
        } else hex.uppercase(Locale.getDefault())
    }

    /**
     * 把十进制数字转换成足位的十六进制字符串,并补全空位
     *
     * @param num
     * @param strLength 字符串的长度
     * @return
     */
    fun decimal2fitHex(num: Long, strLength: Int): String {
        val hexStr = decimal2fitHex(num)
        val stringBuilder = StringBuilder(hexStr)
        while (stringBuilder.length < strLength) {
            stringBuilder.insert(0, '0')
        }
        return stringBuilder.toString()
    }

    fun fitDecimalStr(dicimal: Int, strLength: Int): String {
        val builder = StringBuilder(dicimal.toString())
        while (builder.length < strLength) {
            builder.insert(0, "0")
        }
        return builder.toString()
    }

    /**
     * 字符串转十六进制字符串
     *
     * @param str
     * @return
     */
    fun str2HexString(str: String): String {
        val chars = "0123456789ABCDEF".toCharArray()
        val sb = StringBuilder()
        var bs: ByteArray? = null
        try {
            bs = str.toByteArray(charset("utf8"))
        } catch (e: Exception) {
            e.printStackTrace()
        }
        var bit: Int
        for (i in bs!!.indices) {
            bit = bs[i].toInt() and 0x0f0 shr 4
            sb.append(chars[bit])
            bit = bs[i].toInt() and 0x0f
            sb.append(chars[bit])
        }
        return sb.toString()
    }

    /**
     * 把十六进制表示的字节数组字符串，转换成十六进制字节数组
     *
     * @param
     * @return byte[]
     */
    fun hexStr2bytes(hex: String): ByteArray {
        val len = hex.length / 2
        val result = ByteArray(len)
        val achar = hex.uppercase(Locale.getDefault()).toCharArray()
        for (i in 0 until len) {
            val pos = i * 2
            result[i] = (hexChar2byte(achar[pos]) shl 4 or hexChar2byte(
                achar[pos + 1]
            )).toByte()
        }
        return result
    }

    /**
     * 把16进制字符[0123456789abcde]（含大小写）转成字节
     *
     * @param c
     * @return
     */
    private fun hexChar2byte(c: Char): Int {
        return when (c) {
            '0' -> 0
            '1' -> 1
            '2' -> 2
            '3' -> 3
            '4' -> 4
            '5' -> 5
            '6' -> 6
            '7' -> 7
            '8' -> 8
            '9' -> 9
            'a', 'A' -> 10
            'b', 'B' -> 11
            'c', 'C' -> 12
            'd', 'D' -> 13
            'e', 'E' -> 14
            'f', 'F' -> 15
            else -> -1
        }
    }

    fun combineByteArray(a: ByteArray, b: ByteArray): ByteArray {
        val combine = ByteArray(a.size + b.size)
        System.arraycopy(a, 0, combine, 0, a.size)
        System.arraycopy(b, 0, combine, a.size, b.size)
        return combine
    }

    fun isByteEqual(a: Byte, b: Byte): Boolean {
        return if (byte2int(a) == byte2int(
                b
            )
        ) {
            true
        } else false
    }

    fun byte2int(data: Byte): Int {
        return data.toInt() and 0xff
    }

    fun getXor(datas: ByteArray): Byte {
        var temp = datas[0]
        for (i in 1 until datas.size) {
            temp = (temp.toInt() xor datas[i].toInt()).toByte()
        }
        return temp
    }

    fun str2HexStr(target: String, len: Int): String? {
        var hexStr: String = str2HexString(target)
        while (hexStr.length < len) {
            hexStr = "0$hexStr"
        }
        return hexStr
    }

    /**
     * 字符串转字节数组
     * @param str
     * @return
     */
    fun hexToByteArray(str: String): ByteArray? {
        var str = str
        var result: ByteArray? = null
        try {
            var hexLen = str.length
            if (hexLen % 2 == 1) {
                hexLen++
                result = ByteArray(hexLen / 2)
                str = "0$str"
            } else {
                result = ByteArray(hexLen / 2)
            }
            var j = 0
            var i = 0
            while (i < hexLen) {
                result[j] =
                    hexToByte(str.substring(i, i + 2))
                j++
                i += 2
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            Log.e(
                "ByteUtil",
                "字符串转字节数组异常：" + e.message
            )
        }
        return result
    }

    /**
     *
     * @param hexStr
     * @return
     */
    private fun hexToByte(hexStr: String): Byte {
        return hexStr.toInt(16).toByte()
    }

    fun hexStringToString(s: String?): String? {
        var s = s
        if (s == null || s == "") {
            return null
        }
        s = s.replace(" ", "")
        val baKeyword = ByteArray(s.length / 2)
        for (i in baKeyword.indices) {
            try {
                baKeyword[i] = (0xff and s.substring(i * 2, i * 2 + 2).toInt(16)).toByte()
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
        }
        try {
            s = String(baKeyword, charset("UTF-8"))
            ""
        } catch (e1: java.lang.Exception) {
            e1.printStackTrace()
        }
        return s
    }

    fun combineBytes(vararg bytes: ByteArray): ByteArray {
        return try {
            var temp = byteArrayOf()
            bytes.forEach { bytesItem ->
                temp = combineByteArray(temp, bytesItem)
            }
            temp
        }catch (e: Exception){
            e.printStackTrace()
            byteArrayOf()
        }
    }
}
